/*
 ES6 对象的 一组 静态方法：
  Object.defineProperty(obj/arr, prop/index, descriptor)
  Object.defineProperties(obj/arr, descriptors)
  作用：给对象定义属性（一次只能定义一个属性），
           目的是 对属性做 约束 和 限制

属性描述符，是一个配置对象，可以包括如下配置选项：

Object.defineProperty(obj, prop, {
  value: 该属性对应的值，默认值是undefined,
  configurable: 属性是否能被删除，默认值是false，不可删除
  enumerable: 属性是否可枚举，默认值是false，不可枚举（不可被for...in遍历出来）
  writable: 属性是否能被修改，默认值是false，不可修改，
  get () {
  },
  set () {
  },
}) 
注意事项：
  添加value和writable属性了， 就不能添加了getter和setter访问器，二者不能共存
*/

const pretty = {
  name: '李沁',
  height: 166,
  _age: 18
}

// 定义 age 属性，不传属性描述符，走默认配置
Object.defineProperty(pretty, 'age', {})
// 可获取，值是undefined
console.log(pretty.age)
// 不可删除
// delete pretty.age
console.log(pretty)
// 不可枚举
for (let key in pretty) {
  console.log(key)
}
// 不可修改
pretty.age = 18
console.log(pretty)

const arr = [7, 30]
// 给下标为 2 定义一个元素，值是11，可枚举, 不可删除，不可修改
Object.defineProperty(arr, 2, {
  value: 11,
  enumerable: true,
  configurable: false,
  writable: false
})
// arr.pop()

// 给 obj 添加一个 age 属性，要求：
// 1. 不可枚举
// 2. 不可删除
// 3. 获取的值是18
// 4. 修改的年龄需在 18 — 30 之间，否则赋值为20
Object.defineProperty(pretty, 'age', {
  configurable: false,
  enumerable: false,
  get () {
    return 18
  },
  set (newVal) {
    if (newVal < 18 || newVal > 30) {
      newVal = 20
    }
    this._age = newVal
  }
})
pretty.age = 32
console.log(pretty)


// 给 obj 同时定义多个属性，性别和体重
// Object.defineProperties(pretty, {
//   gender: {
//     value: '女',
//     configurable: false,
//     writable: false,
//     enumerable: true
//   },
//   weight: {
//     value: 44,
//     configurable: false,
//     writable: false,
//     enumerable: false
//   }
// })
console.log(pretty)
// 同时 给 arr 下标 为3，4  定义 两个 元素，8，24
// Object.defineProperties(arr, {
//   3: {
//     value: 22
//   },
//   4: {
//     value: 33
//   }
// })
console.log(arr)
